﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using PdfSharp;
using PdfSharp.Drawing;
using PdfSharp.Drawing.Layout;
using PdfSharp.Pdf;
using PdfSharp.Pdf.IO;
using PayexpDAL;
using System.IO;
using Utilities;
using System.Diagnostics;
using System.Threading; 

namespace Moneymatters
{
    internal static class PDFCreator
    {
        internal static void CreateVoucher(TransactionMaster transactionMaster)
        {
            PdfDocument pdfDocument = new PdfDocument();
            PdfPage page = pdfDocument.AddPage();

            XGraphics gfx = XGraphics.FromPdfPage(page);
            XTextFormatter tf = new XTextFormatter(gfx);


            bool isVoucher = false;
            if (transactionMaster.Head.Equals("head_expense"))
            {
                isVoucher = true;
            }

            WriteToPDF(tf, isVoucher, page, transactionMaster, 0, false);
            WriteToPDF(tf, isVoucher, page, transactionMaster, 430, true);

            //string destinationPath = AppSettingsLoader.AppSettingsValuesMap[Constants.AppSettingsKeys.VoucherReceiptLocation];
            string destinationPath = SettingsAndStaticListLoader.GetAppSettingValue(Constants.AppSettingsKeys.VoucherReceiptLocation);
            if (Utils.CreateDestinationPath(destinationPath))
            {
                string dateTimeForFileName = DateTime.Now.Day.ToString() + "-" + Utils.GetMonth(DateTime.Now.Month) + "-" + DateTime.Now.Year + "-" + DateTime.Now.ToLongTimeString().Replace(":", "");
                string voucherReceiptNumberForFileName = (transactionMaster.VoucherReceiptPrefix + transactionMaster.VoucherReceiptNumber.ToString()).Replace("/", "-") + "_" + dateTimeForFileName + ".pdf";
                //string fileTime = DateTime.Now.ToString().

                
                destinationPath = Path.Combine(destinationPath, voucherReceiptNumberForFileName);
               
                pdfDocument.Save(destinationPath);

                pdfDocument.Close();

            }

            Process.Start(destinationPath);
        }

        static void WriteToPDF(XTextFormatter tf, bool isVoucher, PdfPage page, TransactionMaster transactionMaster, int Y, bool isOfficeCopy)
        {
            // Header
            XFont font = new XFont("Verdana", 14, XFontStyle.Bold);
            tf.Alignment = XParagraphAlignment.Center;
            tf.DrawString("Mahindra Royale Co-Op Hsg Society Ltd.", font, XBrushes.Black,
                                new XRect(0, Y+20, page.Width, page.Height),
                                XStringFormats.TopLeft);

            font = new XFont("Verdana", 10, XFontStyle.Regular);

            tf.DrawString("CTS 6020, Pimpri-Nehrunagar Road, Near Eaton, Pimpri, Pune - 411018.", font, XBrushes.Black,
                                new XRect(0, Y + 40, page.Width, page.Height),
                                XStringFormats.TopLeft);

            tf.DrawString("REG NO: PNA/PNA-(3)HSG/(TC)/11070/2011 DT: 20-05-2011", font, XBrushes.Black,
                                new XRect(0, Y + 55, page.Width, page.Height),
                                XStringFormats.TopLeft);
            // Receipt or Voucher 
            font = new XFont("Verdana", 10, XFontStyle.Bold);
            tf.Alignment = XParagraphAlignment.Left;
            if (isVoucher)
            {
                tf.DrawString("PAYMENT VOUCHER", font, XBrushes.Black,
                                new XRect(50, Y + 85, page.Width, page.Height),
                                        XStringFormats.TopLeft);
            }
            else
            {
                tf.DrawString("PAYMENT RECEIPT", font, XBrushes.Black,
                                new XRect(50, Y + 85, page.Width, page.Height),
                                        XStringFormats.TopLeft);
            }

            font = new XFont("Verdana", 10, XFontStyle.Regular);
            string voucherReceiptNumber = "(Ref: " + transactionMaster.VoucherReceiptPrefix + transactionMaster.VoucherReceiptNumber.ToString() + ")";
            tf.DrawString(voucherReceiptNumber, font, XBrushes.Black,
                            new XRect(165, Y + 85, page.Width, page.Height),
                                    XStringFormats.TopLeft);

            // Transaction and Receipt/ Voucher date 
            font = new XFont("Verdana", 8, XFontStyle.Bold);
            tf.DrawString("Transaction Date: ", font, XBrushes.Black,
                                new XRect(50, Y + 105, page.Width, page.Height),
                                        XStringFormats.TopLeft);

            font = new XFont("Verdana", 8, XFontStyle.Regular);
            string transactionDate = transactionMaster.TransactionDate.Day.ToString() + "-" + Utils.GetMonth(transactionMaster.TransactionDate.Month) + "-" + transactionMaster.TransactionDate.Year;// +"/ ";
            tf.DrawString(transactionDate, font, XBrushes.Black,
                                new XRect(135, Y + 105, page.Width, page.Height),
                                        XStringFormats.TopLeft);

            font = new XFont("Verdana", 8, XFontStyle.Bold);
            if (isVoucher)
            {
                tf.DrawString("Voucher Date: ", font, XBrushes.Black,
                                new XRect(200, Y + 105, page.Width, page.Height),
                                        XStringFormats.TopLeft);
            }
            else
            {
                tf.DrawString("Receipt Date: ", font, XBrushes.Black,
                                new XRect(200, Y + 105, page.Width, page.Height),
                                        XStringFormats.TopLeft);
            }

            string today = DateTime.Now.Day.ToString() + "-" + Utils.GetMonth(DateTime.Now.Month) + "-" + DateTime.Now.Year;
            today = today + " " + DateTime.Now.ToString("hh:mm tt", new System.Globalization.CultureInfo("en-US"));
            font = new XFont("Verdana", 8, XFontStyle.Regular);
            tf.DrawString(today, font, XBrushes.Black,
                                new XRect(270, Y + 105, page.Width, page.Height),
                                        XStringFormats.TopLeft);

            // Place to enter the name
            string inFavourOf = string.Empty;
            font = new XFont("Verdana", 8, XFontStyle.Bold);
            if (isVoucher)
            {
                inFavourOf = "Paid To: ";
                tf.DrawString(inFavourOf, font, XBrushes.Black,
                            new XRect(50, Y + 125, page.Width, page.Height),
                                    XStringFormats.TopLeft);
            }
            else
            {
                inFavourOf = "Received From: ";
                tf.DrawString(inFavourOf, font, XBrushes.Black,
                            new XRect(50, Y + 125, page.Width, page.Height),
                                    XStringFormats.TopLeft);
            }

            if (!string.IsNullOrEmpty(transactionMaster.Narration))
            {
                int x = 0;
                if (isVoucher)
                {
                    x = 90;
                }
                else
                {
                    x = 130;
                }
                
                font = new XFont("Verdana", 8, XFontStyle.Italic);
                List<string> linesToWrite = SplitNarration(transactionMaster.Narration);
                string firstLine = linesToWrite[0];
                tf.DrawString(firstLine, font, XBrushes.Black,
                            new XRect(x, Y + 125, page.Width, page.Height),
                                    XStringFormats.TopLeft);

                linesToWrite.RemoveAt(0);

                int y = Y + 125;
                foreach (string line in linesToWrite)
                {
                    y = y + 20;
                    tf.DrawString(line, font, XBrushes.Black,
                            new XRect(x, y, page.Width, page.Height),
                                    XStringFormats.TopLeft);
                }
            }
            
            // Amount
            font = new XFont("Verdana", 8, XFontStyle.Bold);
            tf.DrawString("Amount: Rs ", font, XBrushes.Black,
                            new XRect(50, Y + 185, page.Width, page.Height),
                                    XStringFormats.TopLeft);
            font = new XFont("Verdana", 8, XFontStyle.Regular);
            tf.DrawString(transactionMaster.TransactionAmount.ToString(), font, XBrushes.Black,
                            new XRect(105, Y + 185, page.Width, page.Height),
                                    XStringFormats.TopLeft);
            
            string[] splitString = transactionMaster.TransactionAmount.ToString().Split(new string[] { "." }, StringSplitOptions.RemoveEmptyEntries);

            string wholePart = string.Empty;
            string decimalPart = string.Empty;

            int wholePartInt = 0;
            int decimalPartInt = 0;

            if (splitString != null && splitString.Count() > 0)
            {
                wholePart = splitString[0];
                int.TryParse(wholePart, out wholePartInt);

                if (splitString.Count() > 1)
                {
                    decimalPart = splitString[1];
                    int.TryParse(decimalPart, out decimalPartInt);
                }
            }

            if (wholePartInt > 0)
            {
                string amountInWords = NumberToWords.GetNumberAsWords(wholePartInt).ToUpper();
                if (decimalPartInt > 0)
                {
                    string paiseInWords = NumberToWords.GetNumberAsWords(decimalPartInt);
                    amountInWords = amountInWords + " & Paise " + paiseInWords.ToUpper();
                }

                amountInWords = "(" + amountInWords + " Only.)";

                font = new XFont("Verdana", 7, XFontStyle.Regular);
                tf.DrawString(amountInWords.ToUpper(), font, XBrushes.Black,
                         new XRect(50, Y + 195, page.Width, page.Height),
                                 XStringFormats.TopLeft);

            }

            // Mode of payment
            font = new XFont("Verdana", 8, XFontStyle.Bold);
            tf.DrawString("Mode of Payment: ", font, XBrushes.Black,
                              new XRect(50, Y + 215, page.Width, page.Height),
                                      XStringFormats.TopLeft);
            
            font = new XFont("Verdana", 8, XFontStyle.Regular);
            if (transactionMaster.TransactionModeValue.Equals("transaction_mode_cash"))
            {
                tf.DrawString("Cash", font, XBrushes.Black,
                              new XRect(135, Y + 215, page.Width, page.Height),
                                      XStringFormats.TopLeft);
            }

            if (transactionMaster.TransactionModeValue.Equals("transaction_mode_neft"))
            {
                string mode = "NEFT";
                tf.DrawString(mode, font, XBrushes.Black,
                              new XRect(135, Y + 215, page.Width, page.Height),
                                      XStringFormats.TopLeft);
            }

            if (transactionMaster.TransactionModeValue.Equals("transaction_mode_cheque"))
            {
                string mode = "Cheque";
                tf.DrawString(mode, font, XBrushes.Black,
                              new XRect(135, Y + 215, page.Width, page.Height),
                                      XStringFormats.TopLeft);

                foreach (TransactionMasterChequeDetail transactionMasterChequeDetail in transactionMaster.TransactionMasterChequeDetails)
                {
                    string bankName = string.Empty;
                    if (SettingsAndStaticListLoader.StaticListMap[Constants.TableConstants.StaticListConstants.bankname].Count > 0)
                    {
                        var bankDetails = SettingsAndStaticListLoader.StaticListMap[Constants.TableConstants.StaticListConstants.bankname].Where(
                                                                                                        t => t.ListItemCode.Equals(transactionMasterChequeDetail.ChequeDrawnOnBank)).FirstOrDefault();
                        if (bankDetails != null)
                        {
                            bankName = bankDetails.ListItemValue + ", ";
                        }
                    }

                    font = new XFont("Verdana", 8, XFontStyle.Bold);
                    tf.DrawString("Cheque Details: ", font, XBrushes.Black,
                                new XRect(50, Y + 225, page.Width, page.Height),
                                        XStringFormats.TopLeft);
                    
                    font = new XFont("Verdana", 8, XFontStyle.Regular);
                    string chequeDetails = bankName + "No " + transactionMasterChequeDetail.ChequeNumber + ", Dated " +
                                                                                                        transactionMasterChequeDetail.ChequeDate.ToShortDateString();
                    tf.DrawString(chequeDetails, font, XBrushes.Black,
                                new XRect(130, Y + 225, page.Width, page.Height),
                                        XStringFormats.TopLeft);

                }
            }

            // Head details  - the if statement is just to change the Y value below :)
            if (transactionMaster.TransactionModeValue.Equals("transaction_mode_cheque"))
            {
                font = new XFont("Verdana", 8, XFontStyle.Bold);
                tf.DrawString("Towards: ", font, XBrushes.Black,
                                  new XRect(50, Y + 255, page.Width, page.Height),
                                          XStringFormats.TopLeft);
                
                font = new XFont("Verdana", 8, XFontStyle.Regular);
                tf.DrawString(transactionMaster.GetHeadDetailsComplete(), font, XBrushes.Black,
                              new XRect(100, Y + 255, page.Width, page.Height),
                                      XStringFormats.TopLeft);

                //// Narration
                //font = new XFont("Verdana", 8, XFontStyle.Bold);
                //tf.DrawString("Narration: ", font, XBrushes.Black,
                //                 new XRect(50, Y + 250, page.Width, page.Height),
                //                         XStringFormats.TopLeft);

                //if (!string.IsNullOrEmpty(transactionMaster.Narration))
                //{
                //    font = new XFont("Verdana", 8, XFontStyle.Regular);
                //    tf.DrawString(transactionMaster.Narration, font, XBrushes.Black,
                //                     new XRect(100, Y + 250, page.Width, page.Height),
                //                             XStringFormats.TopLeft);
                //}
            }
            else
            {
                font = new XFont("Verdana", 8, XFontStyle.Bold);
                tf.DrawString("Towards: ", font, XBrushes.Black,
                                  new XRect(50, Y + 235, page.Width, page.Height),
                                          XStringFormats.TopLeft);

                font = new XFont("Verdana", 8, XFontStyle.Regular);
                tf.DrawString(transactionMaster.GetHeadDetailsComplete(), font, XBrushes.Black,
                             new XRect(100, Y + 235, page.Width, page.Height),
                                     XStringFormats.TopLeft);

                //// Narration
                //font = new XFont("Verdana", 8, XFontStyle.Bold);
                //tf.DrawString("Narration: ", font, XBrushes.Black,
                //                 new XRect(50, Y + 230, page.Width, page.Height),
                //                         XStringFormats.TopLeft);

                //if (!string.IsNullOrEmpty(transactionMaster.Narration))
                //{
                //    font = new XFont("Verdana", 8, XFontStyle.Regular);
                //    tf.DrawString(transactionMaster.Narration, font, XBrushes.Black,
                //                     new XRect(100, Y + 230, page.Width, page.Height),
                //                             XStringFormats.TopLeft);
                //}
            }

           

            
            // name and signatures
            string userNameToBePrintedByDefault = string.Empty;
            if(!string.IsNullOrEmpty(transactionMaster.UpdatedBy))
            {
                userNameToBePrintedByDefault =  transactionMaster.UpdatedBy.FirstLetterUpperCaseRestLowerCase();
            }

            font = new XFont("Verdana", 8, XFontStyle.Bold);
            if (isVoucher)
            {
                string preparedBy = "Prepared By: " + userNameToBePrintedByDefault;
                tf.DrawString(preparedBy, font, XBrushes.Black,
                              new XRect(50, Y + 285, page.Width, page.Height),
                                      XStringFormats.TopLeft);

                tf.DrawString("Chairman", font, XBrushes.Black,
                              new XRect(175, Y + 285, page.Width, page.Height),
                                      XStringFormats.TopLeft);
                
                
                tf.DrawString("Secretary", font, XBrushes.Black,
                              new XRect(275, Y + 285, page.Width, page.Height),
                                      XStringFormats.TopLeft);

                tf.DrawString("Treasurer", font, XBrushes.Black,
                              new XRect(375, Y + 285, page.Width, page.Height),
                                      XStringFormats.TopLeft);

                tf.DrawString("Payment Received By:", font, XBrushes.Black,
                              new XRect(475, Y + 285, page.Width, page.Height),
                                      XStringFormats.TopLeft);
            }
            else
            {
                string preparedBy = "Prepared By: " + userNameToBePrintedByDefault;
                tf.DrawString(preparedBy, font, XBrushes.Black,
                              new XRect(50, Y + 285, page.Width, page.Height),
                                      XStringFormats.TopLeft);
                
                string incomeReceivedBy = string.Empty;
                if (transactionMaster.TransactionModeValue.Equals("transaction_mode_cash"))
                {
                    incomeReceivedBy = "Cash Received By: " + userNameToBePrintedByDefault;
                }
                else
                {
                    incomeReceivedBy = "Cheque/DD/Pay Order Received By: " + userNameToBePrintedByDefault;
                }


                if (transactionMaster.TransactionModeValue.Equals("transaction_mode_cash"))
                {
                    tf.DrawString(incomeReceivedBy, font, XBrushes.Black,
                                  new XRect(380, Y + 285, page.Width, page.Height),
                                          XStringFormats.TopLeft);
                }
                else
                {
                    tf.DrawString(incomeReceivedBy, font, XBrushes.Black,
                                  new XRect(330, Y + 285, page.Width, page.Height),
                                          XStringFormats.TopLeft);
                }
            }

            if (isVoucher)
            {
                tf.DrawString("Signature", font, XBrushes.Black,
                          new XRect(50, Y + 330, page.Width, page.Height),
                                  XStringFormats.TopLeft);

                tf.DrawString("Signature", font, XBrushes.Black,
                          new XRect(175, Y + 330, page.Width, page.Height),
                                  XStringFormats.TopLeft);

                tf.DrawString("Signature", font, XBrushes.Black,
                          new XRect(275, Y + 330, page.Width, page.Height),
                                  XStringFormats.TopLeft);

                tf.DrawString("Signature", font, XBrushes.Black,
                          new XRect(375, Y + 330, page.Width, page.Height),
                                  XStringFormats.TopLeft);
                
                tf.DrawString("Signature", font, XBrushes.Black,
                                new XRect(475, Y + 330, page.Width, page.Height),
                                        XStringFormats.TopLeft);
            }
            else
            {
                tf.DrawString("Signature", font, XBrushes.Black,
                          new XRect(50, Y + 330, page.Width, page.Height),
                                  XStringFormats.TopLeft);
                
                if (transactionMaster.TransactionModeValue.Equals("transaction_mode_cash"))
                {

                    tf.DrawString("Signature", font, XBrushes.Black,
                                    new XRect(380, Y + 330, page.Width, page.Height),
                                            XStringFormats.TopLeft);
                }
                else
                {
                    tf.DrawString("Signature", font, XBrushes.Black,
                                    new XRect(330, Y + 330, page.Width, page.Height),
                                            XStringFormats.TopLeft);
                }
            }

            if (!isVoucher && !transactionMaster.TransactionModeValue.Equals("transaction_mode_cash"))
            {
                tf.Alignment = XParagraphAlignment.Center;
                tf.DrawString("*Receipt is valid subject to realization of Cheque/DD/Pay Order* ", font, XBrushes.Black,
                                    new XRect(0, Y + 350, page.Width, page.Height),
                                    XStringFormats.TopLeft);
            }

            if (isOfficeCopy)
            {
                font = new XFont("Verdana", 8, XFontStyle.BoldItalic);
                tf.Alignment = XParagraphAlignment.Center;
                tf.DrawString("[Office Copy]", font, XBrushes.Black,
                                    new XRect(0, Y + 365, page.Width, page.Height),
                                    XStringFormats.TopLeft);
            }
        }

        private static List<string> SplitNarration(string narration)
        {
            List<string> temp = new List<string>();
            if (narration.Length <= 75)
            {
                temp.Add(narration);
                return temp;
            }
            else
            {
                string[] splitString = narration.Split(new string[] { " " }, StringSplitOptions.RemoveEmptyEntries);
                
                string line = string.Empty;
                foreach (string word in splitString)
                {
                    line = line + word + " ";
                    if (line.Length > 100)
                    {
                        temp.Add(line);
                        line = string.Empty;
                    }
                }

                if (!string.IsNullOrEmpty(line))
                {
                    temp.Add(line);
                }

                return temp;
            }
        }
    }
}
